<template>
    <div class="search-result-list">
        <TableModule :tableModule="tableModule" ref="TableModuleRef">
            <template #event>
                <el-button type="primary" @click="formVisible = true">新增</el-button>
                <!-- <el-button type="danger" @click="deleteTask">删除</el-button> -->
            </template>
            <template #tableColumn>
                <el-table-column type="expand" label="详情" fixed="left" width="60px">
                    <template slot-scope="scope" #default="scope">
                        <el-row style="display: flex; margin:0 20px;">
                            <el-col :span="4">
                                <el-descriptions
                                :column="1"
                                size="large"
                                border>
                                <el-descriptions-item>
                                    <template #label>
                                        <div class="cell-item">产品名称</div>
                                    </template>
                                    <el-tag>{{ scope.row.product_name }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item>
                                    <template #label>
                                        <div class="cell-item">使用推理</div>
                                    </template>
                                    <el-tag>{{ scope.row.test_infer }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item>
                                    <template #label>
                                        <div class="cell-item">识别模型</div>
                                    </template>
                                    <el-popover
                                        placement="top-start"
                                        width="auto"
                                        trigger="hover"
                                    >
                                        <template #reference>
                                            <el-tag href="#">{{ scope.row.recognition_models[0] }}</el-tag>
                                        </template>
                                        <div v-for="(item, index) in scope.row.recognition_models" style="display: inline-block;">
                                            <el-tag>{{ item }}</el-tag>
                                            <span v-if="index < scope.row.recognition_models.length -1">&nbsp;</span>
                                        </div>
                                    </el-popover>
                                </el-descriptions-item>
                                <el-descriptions-item>
                                    <template #label>
                                        <div class="cell-item">数据路径</div>
                                    </template>
                                    {{ scope.row.test_data }}
                                </el-descriptions-item>
                                <el-descriptions-item>
                                    <template #label>
                                        <div class="cell-item">svn</div>
                                    </template>
                                    {{ scope.row.svn }}
                                </el-descriptions-item>
                            </el-descriptions>
                                </el-col>
                                <el-col :span="20">
                                    <el-card style="border-radius: 0%; border-left: none; margin-top: 10px; padding: 8px 20px;" shadow="never">
                                        <!-- 进度条 -->
                                        <el-progress 
                                        status="success"
                                        :percentage=getPercentage(scope.row.test_status)
                                        :stroke-width="10" 
                                        :show-text="false"
                                        :indeterminate="getIndeterminate(scope.row.test_status)"
                                        :duration="3"/>  
                                        <!-- 测试任务日志输出框 -->
                                        <el-card class="box-card" shadow="never">
                                            <view class="type-writer-content" v-for="(item, index) in list" :key="index">
                                                <div class="local-task-log" v-if="item.uid == scope.row.taskid">
                                                    <type-writer :uid="item.uid" :contentList="item.contentList" :delaytime="item.delayTime"/>
                                                </div>
                                                <div class="local-task-log" v-else-if="logList.get(scope.row.taskid)">
                                                    <div v-html="logList.get(scope.row.taskid)"></div>
                                                </div>
                                                <div v-else>
                                                    <el-empty :image-size="100"/>
                                                </div>
                                            </view>
                                        </el-card>
                                    </el-card>
                                </el-col>
                        </el-row>
                    </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" width="300">
                    <template slot-scope="scope" #default="scope">
                        <template v-if="scope.row.test_status === '未开始'">
                            <el-button type="primary" size="small" :icon="VideoPlay" @click="configParam(scope.row)">开始</el-button>
                        </template>
                        <template v-else-if="scope.row.test_status === '进行中' || scope.row.test_status === '排队中'">
                            <el-popconfirm
                            :width="200"
                            confirm-button-text="确认"
                            cancel-button-text="取消"
                            :icon="InfoFilled"
                            icon-color="#626AEF"
                            title="确定要终止任务吗？"
                            @confirm="stopTask(scope.row.taskid)"
                            >
                                <template #reference>
                                    <el-button type="primary" size="small" plain>
                                        <el-icon class="is-loading"><Loading /></el-icon><span>终止</span>
                                    </el-button>
                                </template>
                            </el-popconfirm>
                        </template>
                        <template v-else>
                            <el-button type="primary" :icon="Refresh" size="small" @click="fuceDialog(scope.row)">复测</el-button>
                        </template>
                        <el-popconfirm
                            :width="200"
                            confirm-button-text="确认"
                            cancel-button-text="取消"
                            :icon="InfoFilled"
                            icon-color="#626AEF"
                            title="确定要删除任务吗？"
                            @confirm="deleteTask(scope.row.taskid)"
                        >
                            <template #reference>
                                <el-button type="danger" :icon="Delete" size="small">删除</el-button>
                            </template>
                        </el-popconfirm>
                        <el-button type="success" :icon="Download" size="small" @click="downloadReport(scope.row.taskid)" :disabled="downloadStatus(scope.row.test_status)" plain>测试报告</el-button>
                    </template>
                </el-table-column>
            </template>
        </TableModule>
    </div>

    <!-- 新增测试任务弹窗 -->
    <el-drawer v-model="formVisible" title="新增测试任务" size="50%" destroy-on-close>
        <TaskForm @task-added="closeDrawer" :user="username"/>
    </el-drawer>

    <!-- 开始测试任务弹窗 -->
    <el-dialog v-model="configParamVisible" title="请确认测试参数" width="40%" destroy-on-close style="border-radius: 8px;">
        <easy-form label-position="left" ref="easyFormRef" :fieldList="fieldList" :model="model" label-width="80px" style="display:flex;flex-direction:column;align-items:flex-start;justify-content: center;margin-top: 20px; margin-left: 20px;">
            <template #buttons="{ model, formRef }">
                <div>
                    <el-button type="primary" @click="handleSubmit(model, formRef)">确认</el-button>
                    <el-button @click="configParamVisible=false">取消</el-button>
                </div>
            </template>
        </easy-form>
    </el-dialog>

    <!-- 复测弹窗 -->
    <el-dialog v-model="fuceVisible" width="40%" destroy-on-close title="请确认测试环境" style="border-radius: 8px;">
        <el-text size="large">是否使用原始测试环境进行复测？否则将重新打包测试环境。</el-text>
        <template #footer>
            <el-button @click="fuceVisible = false">取消</el-button>
            <el-button type="danger" @click="configParam(taskRow)">否</el-button>
            <el-button type="primary" @click="configParam(taskRow)">是</el-button>
        </template>
    </el-dialog>

</template>
  
<script lang="ts" setup>
import { TaskService } from '@/api/task';
import { useFakeProgress  } from '@/hooks/useFakeProgress';
import { ref } from 'vue';
import { columnsData, queryData } from '@/config/table.ts';
import { VideoPlay, Delete, InfoFilled, Refresh, Loading, Download } from '@element-plus/icons-vue'
import TaskForm from '@/views/taskForm.vue';
import { message } from "ant-design-vue";
import { storeToRefs } from 'pinia';
import appStore from '@/pinia';
import { testParam } from '@/config/task';
import { FormInstance } from 'element-plus';
import {RedisService } from '@/api/redis';
import { FilesService } from '@/api/files';

const { username } = storeToRefs(appStore.userModule);
const { socketMessage } = storeToRefs(appStore.socketModule);
const fieldList: Form.FieldItem[] = testParam.base
const model = ref(<Record<string, any>>({
    instance_num: [1],
    duplicate_num: 1,
    loop_num: 1
}))

const easyFormRef = ref();
const handleSubmit = async (model: any, formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.validate((valid) => {
        if (valid) {
            startTask(taskRow.value, model)
        }else {
            console.log('error submit!')
            return false
        }
    })
    
}

// taskData：用于存储完整的测试任务数据信息
const taskData = ref()
// 存储测试任务的日志
const logList = new Map<string, Ref<any>>();
const getAllTasks = async (page: number, limit: number, filteredDataList: never[] = []) => {
    state.loading = true
    try {
        const res = await TaskService.getAllTasks();
        state.loading = false
        // 计算起始索引和结束索引，根据当前页码和每页数据条数
        const startIndex = (page - 1) * limit;
        const endIndex = startIndex + limit;
        // 获取当前页的数据段
        if (Object.keys(state.queryForm).length !== 0){
            const currentPageData = filteredDataList.slice(startIndex, endIndex);
            state.dataList = currentPageData
            state.pages.total = filteredDataList.length
        }else{
            const currentPageData = res.data.slice(startIndex, endIndex);
            state.dataList = currentPageData
        }
        state.dataList.forEach(async (item: any) =>{
            if (item.test_status === '通过'){
                const result = await FilesService.getTaskLog(item.taskid.toString());
                if (result.data !== null){
                    logList.set(item.taskid, result.data);
                }  
            }
        });
        state.originalDataList = res.data
        taskData.value = res.data
        
    } catch (error) {
        window.console.error(error)
    }
}

const state = reactive({
    columns: columnsData, // 表格配置
    query: queryData, // 查询条件配置
    queryForm: {}, // 查询form表单
    loading: false, // 加载状态
    dataList: [], // 列表数据
    originalDataList: [],
    pages: { // 分页数据
        total: 0,
        limit: 10,
        page: 1,
    }
})
const { loading, dataList, columns, pages, query, queryForm, originalDataList } = toRefs(state)
const TableModuleRef = ref()
const list = ref([
    {
        contentList: [] as any,
        delayTime: 0,
        uid: 0
    }  
])
// 传给子组件的
const tableModule = ref<Object>({
    editInputBlur: editInputBlur, // 可编辑单元的，失去焦点时的回调
    callback: getAllTasks, // 回调，子组件中可以看到很多调用callback的，这里对应的是获取列表数据的方法
    queryForm: queryForm,
    columns: columns,
    dataList: dataList,
    originalDataList: originalDataList,
    loading: loading,
    pages: pages,
    query: query,
})

const formVisible = ref(false)
const closeDrawer = (value: number) => {
    formVisible.value = false
    state.pages.total += value
    state.pages.page = Math.ceil(state.pages.total / state.pages.limit)
    getAllTasks(state.pages.page, state.pages.limit)
}

const fakeProfress = useFakeProgress()
const { start, end } = fakeProfress

const configParamVisible = ref(false);
const taskRow = ref();
const configParam = async (row: any) => {
    configParamVisible.value = true
    taskRow.value = row
    fuceVisible.value = false
}

const fuceVisible = ref(false);
const fuceDialog = async (row: any) => {
    fuceVisible.value = true
    taskRow.value = row
}

// TODO：开始任务事件
async function startTask(row: any, model: any) {
    // TODO：复测功能
    configParamVisible.value = false
    let filename = null
    await RedisService.getRedis(row.taskid.toString()).then(result => {
        filename = result.data
    })
    if (filename != null) {
        await TaskService.startTask(filename, "http://192.168.31.251:9988/addtask", JSON.stringify(model))
    }else {
        const create_time = new Date(row.create_time)
        const timestamp: number = Math.floor(create_time.getTime() / 1000)
        // TODO：开始执行任务
        await TaskService.startTask(timestamp.toString(), "http://192.168.31.251:9988/addtask", JSON.stringify(model))
        // TODO：在redis中存储时间戳与任务id
        RedisService.setRedis(timestamp.toString(), row.taskid.toString());
        RedisService.setRedis(row.taskid.toString(), timestamp.toString());
    }
    
    // TODO：获取进行中的任务，如有则排队该任务，否则进行该任务
    const runningTask = taskData.value.filter((item: { test_status: string; }) => item.test_status === '进行中');
    if (runningTask.length > 0) {
        await editStatus(row.taskid, "排队中")
    }else {
        taskid.value = row.taskid
        await editStatus(row.taskid, "进行中")
    }
    // TODO：刷新表格数据
    await getAllTasks(state.pages.page, state.pages.limit)  
}

const stopTask = async (taskid: number) => {
    const res = await TaskService.killTask();
    if (res.code == 200) {
        await editStatus(taskid, "终止");
        await editFinishTime(taskid);
        end();
        getAllTasks(state.pages.page, state.pages.limit)
    }else {
        console.error(res.message)
    }
}

const editStatus = async (taskid: number, status: string) => {
    try {
        await TaskService.updateTaskStatus(taskid, status)
    } catch (error) {
        // console.error(error)
    }
}

const editFinishTime = async (taskid: number) => {
    const time = new Date();
    try {
        await TaskService.updateTaskFinishTime(taskid, time)
    }catch (error) {
        //console.error(error)
    }
}

const deleteTask = async (taskid: any) => { // 删除事件
    try {
        const res = await TaskService.deleteTask(taskid);
        message.success(res.message)
    }catch (error) {
        console.error(error)
    }
    state.pages.total--
    getAllTasks(state.pages.page, state.pages.limit)
}

function editInputBlur() {
    console.log('失去焦点回调')
}

const receiveMessage = async (data: any) => {
    if(typeof data === "string" && data.includes("all process done")){
        const temp = taskid.value
        // const key = taskid.value + "log"
        // const value = JSON.stringify(list.value[0].contentList)
        // RedisService.setRedis(key, value)
        await getQueue()
        console.log("temp: " + temp)
        if(temp !== taskid.value){
            await editStatus(taskid.value, "进行中")
        }
        await getAllTasks(state.pages.page, state.pages.limit)
        //list.value[0].contentList = []
    }
    list.value[0].uid = taskid.value;
    list.value[0].contentList.push(data);
    //list.value[0].contentList.join('');
}

const getRunningTask = async () => {
    try {
        const result = await TaskService.getRunning("http://192.168.31.251:9988/getrunning")
        if(result.data.running !== "None"){
            const task = JSON.parse(result.data.running);
            RedisService.getRedis(task.id).then((result) => {
                taskid.value = result.data
            });
        }
    } catch (error) {
        return error
    }
    
}

const queue = ref()
const getQueue = async () => {
    await TaskService.getQueue("http://192.168.31.251:9988/getqueue").then((result) => {
        queue.value = result.data.queue
        const regex = /"id": "(\d+)"/
        const match = regex.exec(queue.value);
        if(match) {
            RedisService.getRedis(match[1]).then((result) => {
                taskid.value = result.data
                console.log(taskid.value)
            })
        }
    })
}

const getPercentage = (status: string) => {
    return status === "通过" ? 100 : 0
}

const getIndeterminate = (status: string) => {
    return status === "通过" ? false : true
}

const taskid = ref() 
onMounted(async () => {
    await getAllTasks(state.pages.page, state.pages.limit).then(() => {
        state.pages.total = taskData.value.length;
    });
    appStore.socketModule.connectSocket();
    getRunningTask();
    start();
})

onUnmounted(() => {
    appStore.socketModule.closeSocket();
})

watch(socketMessage, (newData) => {
    receiveMessage(newData);
})

const downloadStatus = (task_status: any) => {
    if (task_status === "通过" || task_status === "不通过") {
        return false;
    }else {
        return true;
    }
}

const downloadReport = async (taskid: number) => {
    await FilesService.downloadReport(taskid.toString(), "http://192.168.31.251:9988/download").then((result) => {
        const blob = new Blob([result.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = '测试报告' + taskid + '.xlsx';
        link.style.display = 'none';
        document.body.appendChild(link)
        link.click();
        URL.revokeObjectURL(url);
    });
}

</script>

<style scoped>
.box-card {
    overflow-y: auto;
    height: 200px;
    border: none;
}

.type-writer-content {
    height: 200PX;
    overflow: auto;
    display: flex;
    flex-direction: column-reverse;
}
.local-task-log {
    white-space: pre-wrap;
}
#components-form-demo-advanced-search .ant-form {
  max-width: none;
}
#components-form-demo-advanced-search .search-result-list {
  margin-top: 16px;
  border: 1px dashed #e9e9e9;
  border-radius: 2px;
  background-color: #fafafa;
  min-height: 200px;
  text-align: center;
  padding-top: 80px;
}
[data-theme='dark'] .ant-advanced-search-form {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid #434343;
  padding: 24px;
  border-radius: 2px;
}
[data-theme='dark'] #components-form-demo-advanced-search .search-result-list {
  border: 1px dashed #434343;
  background: rgba(255, 255, 255, 0.04);
}
.el-descriptions {
    margin-top: 10px;
}
.cell-item {
  display: flex;
  align-items: center;
  font-weight: bold;
}

::v-deep .el-card__body {
    padding: 0px !important;
}
</style>
